package com.lsh.order.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * @author ：LiuShihao
 * @date ：Created in 2021/8/22 8:49 下午
 * @desc ：配置资源服务器
 */
@Configuration
@EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {

    /**资源ID*/
    private  String resource_id = "order";
    /**客户端秘钥*/
    private  String client_id = "c1" ;
    /**客户端秘钥*/
    private  String client_secret = "order" ;

    @Autowired
    TokenStore tokenStore;

    /**
     * ResourceServerSecurityConfigurer中主要包括：
     * 1. tokenService：ResourceServerTokenService类的实例，用来实现令牌服务。
     * 2. tokenStore：TokenStore类的实例，指定令牌如何访问，与tokenServices配置可选。
     * 3. resourceId：这个资源服务的ID，属性可选，推荐设置并在授权服务中验证。
     * 4. 其他拓展属性例如tokenExtractor令牌提取器用来提取请求中的令牌。
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

        resources
                //资源ID
                .resourceId(resource_id)
                //自身解析JWT令牌 ，无需调用远程的认证服务器校验令牌
                .tokenStore(tokenStore)
                //验证令牌的服务 调用远程的认证服务器校验令牌
//                .tokenServices(tokenServices())
                .stateless(true);

    }

    /**
     *1. 请求匹配器，用来设置需要进行保护的资源路径，默认的情况是保护资源服务的全部路径。
     * 2. 通过http.authorizeRequest()来设置受保护资源的访问规则。
     * 3. 其他的自定义权限保护规则通过HttpSecurity来进行配置
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                //令牌的范围必须是 order或者 all 其中任意的
                .antMatchers("/**").access("#oauth2.hasAnyScope('ALL','ROLE_ADMIN')")
                //关闭跨域
                .and().csrf().disable()
                //因为使用了token的形式，所以不需要创建Session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }

    /**
     * 资源服务令牌解析服务  远程调用授权服务器校验token
     * @return
     */
//    @Bean
//    public ResourceServerTokenServices tokenServices(){
//        //使用远程服务请求授权服务器校验token,必须指定检验token的url、client_id、client_secret
//        RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
//        remoteTokenServices.setCheckTokenEndpointUrl("http://localhost:8081/oauth2/oauth/check_token");
//        remoteTokenServices.setClientId(client_id);
//        //注意授权服务器使用了new BCryptPasswordEncoder().encode("order")编码，资源服务器不需要编码
//        remoteTokenServices.setClientSecret(client_secret);
//        return remoteTokenServices;
//    }

}
